/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package it.polimi.games.gpicalculator;

import dk.ange.octave.OctaveEngine;
import dk.ange.octave.OctaveEngineFactory;
import dk.ange.octave.type.OctaveDouble;
import it.eng.games.esmi.fcim.controller.FcimActivityJpaController;
import it.eng.games.esmi.fcim.controller.FcimCpuFanJpaController;
import it.eng.games.esmi.fcim.controller.FcimCpuFrequencyJpaController;
import it.eng.games.esmi.fcim.controller.FcimCpuJpaController;
import it.eng.games.esmi.fcim.controller.FcimCpuLoadJpaController;
import it.eng.games.esmi.fcim.controller.FcimCpuOneJpaController;
import it.eng.games.esmi.fcim.controller.FcimCpuSshJpaController;
import it.eng.games.esmi.fcim.controller.FcimEnvAirJpaController;
import it.eng.games.esmi.fcim.controller.FcimEnvConsumptionJpaController;
import it.eng.games.esmi.fcim.controller.FcimEnvHumidityJpaController;
import it.eng.games.esmi.fcim.controller.FcimEnvTemperatureJpaController;
import it.eng.games.esmi.fcim.controller.FcimHddOneJpaController;
import it.eng.games.esmi.fcim.controller.FcimKernelJpaController;
import it.eng.games.esmi.fcim.controller.FcimNetworkJpaController;
import it.eng.games.esmi.fcim.controller.FcimPerformanceCounterJpaController;
import it.eng.games.esmi.fcim.controller.FcimProcessJpaController;
import it.eng.games.esmi.fcim.controller.FcimProcessesJpaController;
import it.eng.games.esmi.fcim.controller.FcimRamJpaController;
import it.eng.games.esmi.fcim.controller.FcimRamOneJpaController;
import it.eng.games.esmi.fcim.controller.FcimRamSshJpaController;
import it.eng.games.esmi.fcim.controller.FcimRecsBoardJpaController;
import it.eng.games.esmi.fcim.controller.FcimRecsMicrocontrollerJpaController;
import it.eng.games.esmi.fcim.controller.FcimServerConsumptionJpaController;
import it.eng.games.esmi.fcim.controller.FcimServerPingJpaController;
import it.eng.games.esmi.fcim.controller.FcimStorageJpaController;
import it.eng.games.esmi.fcim.controller.FcimTemperatureJpaController;
import it.eng.games.esmi.fcim.controller.FcimVmConsumptionJpaController;
import it.eng.games.esmi.fcim.controller.FcimVmOneJpaController;
import it.eng.games.esmi.fcim.controller.FcimVmsOneJpaController;
import it.eng.games.esmi.fcim.entity.FcimActivity;
import it.eng.games.esmi.fcim.entity.FcimCpu;
import it.eng.games.esmi.fcim.entity.FcimCpuFan;
import it.eng.games.esmi.fcim.entity.FcimCpuFrequency;
import it.eng.games.esmi.fcim.entity.FcimCpuLoad;
import it.eng.games.esmi.fcim.entity.FcimCpuOne;
import it.eng.games.esmi.fcim.entity.FcimCpuSsh;
import it.eng.games.esmi.fcim.entity.FcimEnvAir;
import it.eng.games.esmi.fcim.entity.FcimEnvConsumption;
import it.eng.games.esmi.fcim.entity.FcimEnvHumidity;
import it.eng.games.esmi.fcim.entity.FcimEnvTemperature;
import it.eng.games.esmi.fcim.entity.FcimHddOne;
import it.eng.games.esmi.fcim.entity.FcimKernel;
import it.eng.games.esmi.fcim.entity.FcimNetwork;
import it.eng.games.esmi.fcim.entity.FcimProcess;
import it.eng.games.esmi.fcim.entity.FcimProcesses;
import it.eng.games.esmi.fcim.entity.FcimRam;
import it.eng.games.esmi.fcim.entity.FcimRamOne;
import it.eng.games.esmi.fcim.entity.FcimRamSsh;
import it.eng.games.esmi.fcim.entity.FcimRecsBoard;
import it.eng.games.esmi.fcim.entity.FcimRecsMicrocontroller;
import it.eng.games.esmi.fcim.entity.FcimServerConsumption;
import it.eng.games.esmi.fcim.entity.FcimServerPing;
import it.eng.games.esmi.fcim.entity.FcimStorage;
import it.eng.games.esmi.fcim.entity.FcimTemperature;
import it.eng.games.esmi.fcim.entity.FcimVmConsumption;
import it.eng.games.esmi.fcim.entity.FcimVmOne;
import it.eng.games.esmi.fcim.entity.FcimVmsOne;
import it.polimi.games.epkb.controller.ComponentJpaController;
import it.polimi.games.epkb.controller.GpiKpiJpaController;
import it.polimi.games.epkb.controller.ObservedComponentJpaController;
import it.polimi.games.epkb.controller.StoredValuesJpaController;
import it.polimi.games.epkb.controller.ThresholdsJpaController;
import it.polimi.games.epkb.entityClasses.GpiKpi;
import it.polimi.games.epkb.entityClasses.GpiKpiInstance;
import it.polimi.games.epkb.entityClasses.ObservedComponent;
import it.polimi.games.epkb.entityClasses.ObservedComponentPK;
import it.polimi.games.epkb.entityClasses.StoredValues;
import it.polimi.games.epkb.entityClasses.Thresholds;
import it.polimi.games.epkb.entityClasses.ThresholdsPK;
//import java.io.Serializable;
import java.io.File;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Query;

/**
 *
 * @author Filippo
 */
public class GpiCalculator {

    /**
     * @uml.property  name="emfEpkb"
     * @uml.associationEnd  multiplicity="(1 1)"
     */
    private EntityManagerFactory emfEpkb;
    /**
     * @uml.property  name="emfFcim"
     * @uml.associationEnd  multiplicity="(1 1)"
     */
    private EntityManagerFactory emfFcim;
    /**
     * @uml.property  name="epkbM"
     * @uml.associationEnd  multiplicity="(1 1)"
     */
    //private EPKBmanager epkbM = new EPKBmanager("EPKB-PU");
    /**
     * @uml.property  name="engineFactory"
     * @uml.associationEnd  multiplicity="(1 1)"
     */
    private OctaveEngineFactory engineFactory;
    /**
     * @uml.property  name="octave"
     * @uml.associationEnd  multiplicity="(0 -1)" elementType="[D"
     */
    private OctaveEngine octave;
    /* contollers */
    GpiKpiJpaController gpiKpiC;
    ComponentJpaController componentC;
    ObservedComponentJpaController ocC;
    StoredValuesJpaController svC;
    ThresholdsJpaController tc;
    FcimRamJpaController jramc;
    FcimProcessJpaController jprocc;
    FcimCpuFrequencyJpaController jcpufrec;
    FcimServerConsumptionJpaController jservconsc;
    FcimCpuSshJpaController jcpusshc;
    FcimRecsMicrocontrollerJpaController jrecsmicroc;
    FcimRamSshJpaController jramsshc;
    FcimRecsBoardJpaController jrecsboardc;
    FcimVmOneJpaController jvmonec;
    FcimVmsOneJpaController jvmsonec;
    FcimCpuJpaController jcpuc;
    FcimCpuLoadJpaController jcpuloadc;
    FcimVmConsumptionJpaController jvmconsc;
    FcimEnvConsumptionJpaController jenvconsc;
    FcimEnvAirJpaController jenvairc;
    FcimNetworkJpaController jnetc;
    FcimServerPingJpaController jservpingc;
    FcimEnvHumidityJpaController jenvhumc;
    FcimKernelJpaController jkernc;
    FcimCpuFanJpaController jcpufanc;
    FcimEnvTemperatureJpaController jenvtempc;
    FcimTemperatureJpaController jtempc;
    FcimProcessesJpaController jprocsc;
    FcimCpuOneJpaController jcpuonec;
    FcimHddOneJpaController jhddonec;
    FcimRamOneJpaController jramonec;
    FcimActivityJpaController jactivityc;
    FcimStorageJpaController jstoragec;
    FcimPerformanceCounterJpaController jperformancec;
    /* queries */
    Query qMain1;
    Query qRamFcim1;
    Query qRamFcim2;
    Query qProcessFcim1;
    Query qProcessFcim2;
    Query qFrequencyFcim1;
    Query qFrequencyFcim2;
    Query qServerConsFcim1;
    Query qServerConsFcim2;
    Query qCpuSshFcim1;
    Query qCpuSshFcim2;
    Query qRecsMicroFcim1;
    Query qRecsMicroFcim2;
    Query qRamSshFcim1;
    Query qRamSshFcim2;
    Query qRecsBoardFcim1;
    Query qRecsBoardFcim2;
    Query qVmOneFcim1;
    Query qVmOneFcim2;
    Query qVmsOneFcim1;
    Query qVmsOneFcim2;
    Query qCpuFcim1;
    Query qCpuFcim2;
    Query qCpuLoadFcim1;
    Query qCpuLoadFcim2;
    Query qVmConsFcim1;
    Query qVmConsFcim2;
    Query qEnvConsFcim1;
    Query qEnvConsFcim2;
    Query qEnvAirFcim1;
    Query qEnvAirFcim2;
    Query qNetworkFcim1;
    Query qNetworkFcim2;
    Query qServerPingFcim1;
    Query qServerPingFcim2;
    Query qEnvHumidityFcim1;
    Query qEnvHumidityFcim2;
    Query qKernelFcim1;
    Query qKernelFcim2;
    Query qCpuFanFcim1;
    Query qCpuFanFcim2;
    Query qEnvTempFcim1;
    Query qEnvTempFcim2;
    Query qTempFcim1;
    Query qTempFcim2;
    Query qProcessesFcim1;
    Query qProcessesFcim2;
    Query qCpuOneFcim1;
    Query qCpuOneFcim2;
    Query qHddOneFcim1;
    Query qHddOneFcim2;
    Query qRamOneFcim1;
    Query qRamOneFcim2;
    Query qActivityFcim1;
    Query qActivityFcim2;
    Query qStorageFcim1;
    Query qStorageFcim2;
    Query qPerformanceFcim1;
    Query qPerformanceFcim2;

    public GpiCalculator(String mFilePath, String octavePath, EntityManagerFactory emfEpkb, EntityManagerFactory emfFcim) {

        this.emfEpkb = emfEpkb;
        this.emfFcim = emfFcim;

        gpiKpiC = new GpiKpiJpaController(this.emfEpkb);
        componentC = new ComponentJpaController(this.emfEpkb);
        ocC = new ObservedComponentJpaController(this.emfEpkb);
        svC = new StoredValuesJpaController(this.emfEpkb);

        tc = new ThresholdsJpaController(this.emfEpkb);


        engineFactory = new OctaveEngineFactory();
        engineFactory.setOctaveProgram(new File(octavePath));
        octave = engineFactory.getScriptEngine();
        String addPath = "addpath('" + mFilePath + "')";
        octave.eval(addPath);
    }

    /**
     * 
     */
    public void closeGpiCalculator() {
        octave.close();
        emfEpkb.close();
        emfFcim.close();
    }

    /**
     * 
     * @param gpiKpiId
     * @param componentId
     */
    public void calculateGpi(String gpiKpiId, String componentId) {

        // Get information on Gpi/Kpi and Component and m-file name
        GpiKpi gpiKpi = gpiKpiC.findGpiKpi(gpiKpiId);
        String mFile = gpiKpi.getExternalLinkToFormula();

        //Ricavo elenco parametri
        //System.out.println("  m-file..." + mFile);
        //System.out.println("  Name...." + gpiKpi.getName());
        qMain1 = gpiKpiC.getEntityManager().createQuery("SELECT s FROM GpiKpiInstance s WHERE s.idGPIKPI=?1 AND s.idComponent=?2");

        qMain1.setParameter(1, gpiKpiC.findGpiKpi(gpiKpiId));
        qMain1.setParameter(2, componentC.findComponent(componentId));

        Collection<GpiKpiInstance> c = qMain1.getResultList();
        Iterator<GpiKpiInstance> i = c.iterator();

        // values array contains the computed values of the parameters of Gpi/Kpi
        // for each parameter the most recent value is get from stored values (if parameter is a Gpi/Kpi)
        // or from Fcim (if parameter is a nagios one)
        BigDecimal[] values = new BigDecimal[c.size()];

        BigDecimal paramValue = null;
        FcimCache fcimCache = null;
        ObservedComponentPK ocPK = null;
        ObservedComponent oc = null;
        String nagiosTable = "";
        String nagiosField = "";

        for (GpiKpiInstance v : c) {

            paramValue = null;
            if (v.getIdReferredGPIKPI() != null) {
                // Gpi/Kpi: retrieve value from stored values
                String referredGpiKpiId = v.getIdReferredGPIKPI().getId();
                StoredValues sv = this.getLastValue(componentId, referredGpiKpiId);
                paramValue = sv.getComputedValue();
            } else {
                // Fcim: retrieve value from Fcim db
                nagiosTable = v.getIdSensorType().getNagiosTable();
                nagiosField = v.getIdSensorType().getNagiosField();
                //System.out.println(nagiosTable + " - " + nagiosField + " - " + componentId);
                // find the serviceId associated to these sensorId and componentId



                ocPK = new ObservedComponentPK(componentId, v.getIdSensorType().getId());
                oc = ocC.findObservedComponent(ocPK);

                //qObservedComponent.setParameter("idComponent", componentId);
                //qObservedComponent.setParameter("idSensorType", v.getIdSensorType().getId());

                //oc = (ObservedComponent) qObservedComponent.getSingleResult();

                //System.out.println("Service object id " + oc.getServiceObjectId());

                if (fcimCache == null || !(fcimCache.isPresent(nagiosTable, nagiosField, oc.getServiceObjectId()))) {
                    //long inizio = System.currentTimeMillis();
                    fcimCache = retryValueFromFcim(nagiosTable, oc.getServiceObjectId());
                    //Logger.getLogger(GpiCalculator.class.getName()).log(Level.INFO, "Leggo parametri da FCIM = " + (System.currentTimeMillis() - inizio));

                }
                paramValue = fcimCache.getParamValue(nagiosTable, nagiosField, oc.getServiceObjectId());
                //Logger.getLogger(GpiCalculator.class.getName()).log(Level.INFO, v.getIdGPIKPI().getName() + " (" + v.getIdComponent() + ") reading " + nagiosTable + " - " + nagiosField + " = " + paramValue);
                // Si potrebbe aggiungere un controllo se paramValue==null non è stato trovato il valore o la tabella
            }

            int position = v.getGpiKpiInstancePK().getPosition();
            values[position - 1] = paramValue;
        }

        //long inizio = System.currentTimeMillis();

        // Compute Gpi/Kpi value using m-file
        BigDecimal computedValue = compute(mFile, values);
        //Logger.getLogger(GpiCalculator.class.getName()).log(Level.INFO, "Calcolo Octave = " + (System.currentTimeMillis() - inizio));



        // Store the computed value in the PEKB storedValues table
        boolean red = this.isRed(componentId, gpiKpiId, computedValue);
        boolean yellow = this.isYellow(componentId, gpiKpiId, computedValue);

        int contextId = 0;

        //inizio = System.currentTimeMillis();

        this.insertGPIKPIValue(componentId, gpiKpiId, contextId, computedValue, red, yellow);

    }

    public boolean insertGPIKPIValue(String ComponentID, String gpiKpiId, int ContextID, BigDecimal value, boolean red, boolean yellow) {
        StoredValues sv = new StoredValues();

      /*  sv.setIdComponent(componentC.findComponent(ComponentID));
        sv.setContextID(ContextID);
        sv.setIdGPIKPI(gpiKpiC.findGpiKpi(gpiKpiId));
        //sv.setId(5);
        sv.setRed(red);
        sv.setDefinitionTime(new Timestamp(System.currentTimeMillis()));
        sv.setComputedValue(value);
        sv.setYellow(yellow);
        svC.create(sv);*/
        
       

        boolean result = true;


        long inizio = System.currentTimeMillis();
  
        
        EntityManager em = this.emfEpkb.createEntityManager();
        em.getTransaction().begin();
        
        Query q = em.createNativeQuery("INSERT INTO stored_values (Id_GPI_KPI, DefinitionTime, Id_Component, ComputedValue, ContextID, Red, Yellow) VALUES (?, ?, ?, ?, ?, ?, ?)");

        q.setParameter(1, gpiKpiId);
        q.setParameter(2, new Timestamp(System.currentTimeMillis()));
        q.setParameter(3, ComponentID);
        q.setParameter(4, value);
        q.setParameter(5, ContextID);
        q.setParameter(6, red);
        q.setParameter(7, yellow);
        
        q.executeUpdate();
        em.getTransaction().commit();
        
        Logger.getLogger(GpiCalculator.class.getName()).log(Level.INFO, "Inserimento vero GPI in DB = " + (System.currentTimeMillis() - inizio));

        return result;
    }

    public boolean isRed(String componentID, String gpiKpiID, BigDecimal value) {
        boolean res;
        ThresholdsPK tPK = new ThresholdsPK();
        tPK.setIdComponent(componentID);
        tPK.setIdGPIKPI(gpiKpiID);
        Thresholds t = tc.findThresholds(tPK);

        if ((value.compareTo(t.getEmergencyRangeHigh()) == 1) || (value.compareTo(t.getEmergencyRangeLow()) == -1)) {
            res = true;
        } else {
            res = false;
        }
        return res;
    }

    public boolean isYellow(String componentID, String gpiKpiID, BigDecimal value) {
        boolean res;
        ThresholdsPK tPK = new ThresholdsPK();
        tPK.setIdComponent(componentID);
        tPK.setIdGPIKPI(gpiKpiID);
        Thresholds t = tc.findThresholds(tPK);

        if (((value.compareTo(t.getNormalRangeHigh()) == 1) & (value.compareTo(t.getEmergencyRangeHigh()) == -1)) || ((value.compareTo(t.getNormalRangeLow()) == -1) & (value.compareTo(t.getEmergencyRangeLow()) == 1))) {
            res = true;
        } else {
            res = false;
        }
        return res;
    }

    /** Returns the stored value of a gpi/kpi indicator, regarding on a given component
     *@return a StoredValues object; a NULL value is returned if no data are found
     */
    public StoredValues getLastValue(String componentId, String gpiKpiId) {

        StoredValues res = null;
        //StoredValuesJpaController svC = new StoredValuesJpaController(emf);


        try {
            Query q1 = svC.getEntityManager().createQuery("SELECT MAX(s.definitionTime) FROM StoredValues s WHERE s.idGPIKPI=?1 AND s.idComponent=?2");
            q1.setParameter(1, gpiKpiC.findGpiKpi(gpiKpiId));
            q1.setParameter(2, componentC.findComponent(componentId));

            Query q2 = svC.getEntityManager().createQuery("SELECT s FROM StoredValues s WHERE s.idGPIKPI=?1 AND s.idComponent=?2 AND s.definitionTime=?3");
            q2.setParameter(1, gpiKpiC.findGpiKpi(gpiKpiId));
            q2.setParameter(2, componentC.findComponent(componentId));
            q2.setParameter(3, (Timestamp) q1.getSingleResult());


            res = (StoredValues) q2.getSingleResult();
        } catch (javax.persistence.NoResultException ee) {
            res = null;
            Logger.getLogger(GpiCalculator.class.getName()).log(Level.INFO, ee.getMessage(), ee);

        }

        return res;
    }

    private BigDecimal compute(String mFile, BigDecimal[] values) {

        // Create string to call the procedure with the actual parameters
        StringBuffer paramb = new StringBuffer("");
        for (int i = 0; i < values.length; i++) {
            paramb = paramb.append(", ");
            paramb = paramb.append(values[i].toString());
        }

        String param = paramb.toString();

        if (param.length() > 1) {
            param = param.substring(2);
        }

        String funcName;
        if (mFile.endsWith(".m")) {
            funcName = mFile.substring(0, mFile.length() - 2);
        } else {
            funcName = mFile;
        }

        String line = funcName.concat("(");
        line = line.concat(param);
        line = line.concat(")");

        // Call the octave procedure in m-file
        // Result is stored in res variable
        BigDecimal res = new BigDecimal(0);
        String resultString = "ris = " + line + ";";
        octave.eval(resultString);

        //Logger.getLogger(GpiCalculator.class.getName()).log(Level.INFO, "Start executing '" + resultString + "' on Octave");

        OctaveDouble result = octave.get(OctaveDouble.class, "ris");
        res = new BigDecimal(result.getData()[0]);

        //Logger.getLogger(GpiCalculator.class.getName()).log(Level.INFO, "End executing '" + resultString + "' on Octave");

        return res;
    }

    private FcimCache retryValueFromFcim(String nagiosTable, String serviceId) {
        FcimCache ret = new FcimCache(nagiosTable, serviceId);

        if (nagiosTable.equalsIgnoreCase("fcim_ram")) {
            
            if (jramc == null)
                jramc = new FcimRamJpaController(this.emfFcim);

            if (qRamFcim1 == null) {
                //qRamFcim1 = jramc.getEntityManager().createQuery("SELECT MAX(e.timestampId.timestamp) FROM FcimRam e WHERE e.serviceId= :serviceId ");
                qRamFcim1 = jramc.getEntityManager().createNativeQuery("SELECT MAX(e.timestamp_id) FROM fcim_ram as e WHERE e.service_id = ?");
            }
            
            //qRamFcim1.setParameter("serviceId", serviceId);
            qRamFcim1.setParameter(1, serviceId);
            //Date ts = (Date) qRamFcim1.getSingleResult();
            Integer ts = (Integer) qRamFcim1.getSingleResult();
            
            if (qRamFcim2 == null) {
                //qRamFcim2 = jramc.getEntityManager().createQuery("SELECT e FROM FcimRam e WHERE e.serviceId = :serviceId AND e.timestampId.timestamp = :ts");
                qRamFcim2 = jramc.getEntityManager().createNativeQuery("SELECT * FROM fcim_ram as e WHERE e.service_id = ? AND e.timestamp_id = ?", FcimRam.class);
            }
            
            //qRamFcim2.setParameter("serviceId", serviceId);
            //qRamFcim2.setParameter("ts", ts);
            qRamFcim2.setParameter(1, serviceId);
            qRamFcim2.setParameter(2, ts);

            Collection<FcimRam> c = qRamFcim2.getResultList();
            Iterator<FcimRam> i = c.iterator();

            if (i.hasNext()) {
                FcimRam v = i.next();
                ret.addValue("total", new BigDecimal(v.getTotal()));
                ret.addValue("used", new BigDecimal(v.getUsed()));
                ret.addValue("free", new BigDecimal(v.getFree()));
                ret.addValue("usage_perc", new BigDecimal(v.getUsagePerc()));
            }

        } else if (nagiosTable.equalsIgnoreCase("fcim_process")) {
            
            if (jprocc == null)
                jprocc = new FcimProcessJpaController(emfFcim);

            if (qProcessFcim1 == null)
                qProcessFcim1 = jprocc.getEntityManager().createQuery("SELECT MAX(e.timestampId.timestamp) FROM FcimProcess e WHERE e.serviceId= :serviceId ");
            
            qProcessFcim1.setParameter("serviceId", serviceId);
            Date ts = (Date) qProcessFcim1.getSingleResult();
            
            if (qProcessFcim2 == null)
                qProcessFcim2 = jprocc.getEntityManager().createQuery("SELECT e FROM FcimProcess e WHERE e.serviceId = :serviceId AND e.timestampId.timestamp = :ts");
            
            qProcessFcim2.setParameter("serviceId", serviceId);
            qProcessFcim2.setParameter("ts", ts);

            Collection<FcimProcess> c = qProcessFcim2.getResultList();
            Iterator<FcimProcess> i = c.iterator();

            if (i.hasNext()) {
                FcimProcess v = i.next();
                ret.addValue("cpu_usage_perc", new BigDecimal(v.getCpuUsagePerc()));
                ret.addValue("ram_usage_perc", new BigDecimal(v.getRamUsagePerc()));
                ret.addValue("cpu_time", new BigDecimal(v.getCpuTime()));
            }
        } else if (nagiosTable.equalsIgnoreCase("fcim_cpu_frequency")) {
            
            if (jcpufrec == null)
                jcpufrec = new FcimCpuFrequencyJpaController(emfFcim);

            if (qFrequencyFcim1 == null) {
                //qFrequencyFcim1 = jcpufrec.getEntityManager().createQuery("SELECT MAX(e.timestampId.timestamp) FROM FcimCpuFrequency e WHERE e.serviceId= :serviceId ");
                qFrequencyFcim1 = jcpufrec.getEntityManager().createNativeQuery("SELECT MAX(e.timestamp_id) FROM fcim_cpu_frequency as e WHERE e.service_id= ?");
            }
            
            //qFrequencyFcim1.setParameter("serviceId", serviceId);
            qFrequencyFcim1.setParameter(1, serviceId);
            Integer ts = (Integer) qFrequencyFcim1.getSingleResult();
            
            if (qFrequencyFcim2 == null) {
                //qFrequencyFcim2 = jcpufrec.getEntityManager().createQuery("SELECT e FROM FcimCpuFrequency e WHERE e.serviceId = :serviceId AND e.timestampId.timestamp = :ts");
                qFrequencyFcim2 = jcpufrec.getEntityManager().createNativeQuery("SELECT * FROM fcim_cpu_frequency as e WHERE e.service_id = ? AND e.timestamp_id = ?", FcimCpuFrequency.class);
            }
            
            //qFrequencyFcim2.setParameter("serviceId", serviceId);
            //qFrequencyFcim2.setParameter("ts", ts);
            qFrequencyFcim2.setParameter(1, serviceId);
            qFrequencyFcim2.setParameter(2, ts);

            Collection<FcimCpuFrequency> c = qFrequencyFcim2.getResultList();
            Iterator<FcimCpuFrequency> i = c.iterator();

            if (i.hasNext()) {
                FcimCpuFrequency v = i.next();
                ret.addValue("frequency", new BigDecimal(v.getFrequency()));
            }
        } else if (nagiosTable.equalsIgnoreCase("fcim_server_consumption")) {
            
            if (jservconsc == null)
                jservconsc = new FcimServerConsumptionJpaController(emfFcim);
            
            if (qServerConsFcim1 == null)
                qServerConsFcim1 = jservconsc.getEntityManager().createQuery("SELECT MAX(e.timestampId.timestamp) FROM FcimServerConsumption e WHERE e.serviceId= :serviceId ");
            
            qServerConsFcim1.setParameter("serviceId", serviceId);
            Date ts = (Date) qServerConsFcim1.getSingleResult();
            
            if (qServerConsFcim2 == null)
                qServerConsFcim2 = jservconsc.getEntityManager().createQuery("SELECT e FROM FcimServerConsumption e WHERE e.serviceId = :serviceId AND e.timestampId.timestamp = :ts");
            
            qServerConsFcim2.setParameter("serviceId", serviceId);
            qServerConsFcim2.setParameter("ts", ts);

            Collection<FcimServerConsumption> c = qServerConsFcim2.getResultList();
            Iterator<FcimServerConsumption> i = c.iterator();

            if (i.hasNext()) {
                FcimServerConsumption v = i.next();
                ret.addValue("power", new BigDecimal(v.getPower()));
                ret.addValue("warning_threshold", new BigDecimal(v.getWarningThreshold()));
                ret.addValue("critical_threshold", new BigDecimal(v.getCriticalThreshold()));
            }
        } else if (nagiosTable.equalsIgnoreCase("fcim_cpu_ssh")) {
            
            if (jcpusshc == null)
                jcpusshc = new FcimCpuSshJpaController(emfFcim);
            
            if (qCpuSshFcim1 == null) {
                //qCpuSshFcim1 = jcpusshc.getEntityManager().createQuery("SELECT MAX(e.timestampId.timestamp) FROM FcimCpuSsh e WHERE e.serviceId= :serviceId ");
                qCpuSshFcim1 = jcpusshc.getEntityManager().createNativeQuery("SELECT MAX(e.timestamp_id) FROM fcim_cpu_ssh as e WHERE e.service_id= ?");
            }
            
            //qCpuSshFcim1.setParameter("serviceId", serviceId);
            qCpuSshFcim1.setParameter(1, serviceId);
            //Date ts = (Date) qCpuSshFcim1.getSingleResult();
            Integer ts = (Integer) qCpuSshFcim1.getSingleResult();
            
            if (qCpuSshFcim2 == null) {
                //qCpuSshFcim2 = jcpusshc.getEntityManager().createQuery("SELECT e FROM FcimCpuSsh e WHERE e.serviceId = :serviceId AND e.timestampId.timestamp = :ts");
                qCpuSshFcim2 = jcpusshc.getEntityManager().createNativeQuery("SELECT * FROM fcim_cpu_ssh e WHERE e.service_id = ? AND e.timestamp_id = ?", FcimCpuSsh.class);
            }
                
            //qCpuSshFcim2.setParameter("serviceId", serviceId);
            //qCpuSshFcim2.setParameter("ts", ts);

            qCpuSshFcim2.setParameter(1, serviceId);
            qCpuSshFcim2.setParameter(2, ts);

            Collection<FcimCpuSsh> c = qCpuSshFcim2.getResultList();
            Iterator<FcimCpuSsh> i = c.iterator();

            if (i.hasNext()) {
                FcimCpuSsh v = i.next();
                ret.addValue("user_perc", new BigDecimal(v.getUserPerc()));
                ret.addValue("nice_perc", new BigDecimal(v.getNicePerc()));
                ret.addValue("sys_perc", new BigDecimal(v.getSysPerc()));
                ret.addValue("iowait_perc", new BigDecimal(v.getIowaitPerc()));
                ret.addValue("idle_perc", new BigDecimal(v.getIdlePerc()));
                ret.addValue("irq_perc", new BigDecimal(v.getIrqPerc()));
                ret.addValue("softirq_perc", new BigDecimal(v.getSoftirqPerc()));
            }
        } else if (nagiosTable.equalsIgnoreCase("fcim_recs_microcontroller")) {
            
            if (jrecsmicroc == null)
                jrecsmicroc = new FcimRecsMicrocontrollerJpaController(emfFcim);

            if (qRecsMicroFcim1 == null)
                qRecsMicroFcim1 = jrecsmicroc.getEntityManager().createNativeQuery("SELECT MAX(e.timestampId.timestamp) FROM FcimRecsMicrocontroller e WHERE e.serviceId= :serviceId ");
            
            qRecsMicroFcim1.setParameter("serviceId", serviceId);
            Date ts = (Date) qRecsMicroFcim1.getSingleResult();
            
            if (qRecsMicroFcim2 == null)
                qRecsMicroFcim2 = jrecsmicroc.getEntityManager().createNativeQuery("SELECT e FROM FcimRecsMicrocontroller e WHERE e.serviceId = :serviceId AND e.timestampId.timestamp = :ts");            
            
            qRecsMicroFcim2.setParameter("serviceId", serviceId);
            qRecsMicroFcim2.setParameter("ts", ts);

            Collection<FcimRecsMicrocontroller> c = qRecsMicroFcim2.getResultList();
            Iterator<FcimRecsMicrocontroller> i = c.iterator();

            if (i.hasNext()) {
                FcimRecsMicrocontroller v = i.next();
                ret.addValue("nr_boards", new BigDecimal(v.getNrBoards()));
                ret.addValue("central_voltage", new BigDecimal(v.getCentralVoltage()));
            }
        } else if (nagiosTable.equalsIgnoreCase("fcim_ram_ssh")) {
            
            if (jramsshc == null)
                jramsshc = new FcimRamSshJpaController(emfFcim);

            if (qRamSshFcim1 == null)
                qRamSshFcim1 = jramsshc.getEntityManager().createQuery("SELECT MAX(e.timestampId.timestamp) FROM FcimRamSsh e WHERE e.serviceId= :serviceId ");
            
            qRamSshFcim1.setParameter("serviceId", serviceId);
            Date ts = (Date) qRamSshFcim1.getSingleResult();
            
            if (qRamSshFcim2 == null)
                qRamSshFcim2 = jramsshc.getEntityManager().createQuery("SELECT e FROM FcimRamSsh e WHERE e.serviceId = :serviceId AND e.timestampId.timestamp = :ts");
            
            qRamSshFcim2.setParameter("serviceId", serviceId);
            qRamSshFcim2.setParameter("ts", ts);

            Collection<FcimRamSsh> c = qRamSshFcim2.getResultList();
            Iterator<FcimRamSsh> i = c.iterator();

            if (i.hasNext()) {
                FcimRamSsh v = i.next();
                ret.addValue("cached", new BigDecimal(v.getCached()));
                ret.addValue("uncached", new BigDecimal(v.getUncached()));
            }
        } else if (nagiosTable.equalsIgnoreCase("fcim_recs_board")) {
            
            if (jrecsboardc == null)
                jrecsboardc = new FcimRecsBoardJpaController(emfFcim);

            if (qRecsBoardFcim1 == null) {
                //qRecsBoardFcim1 = jrecsboardc.getEntityManager().createQuery("SELECT MAX(e.timestampId.timestamp) FROM FcimRecsBoard e WHERE e.serviceId= :serviceId ");
                qRecsBoardFcim1 = jrecsboardc.getEntityManager().createNativeQuery("SELECT MAX(e.timestamp_id) FROM fcim_recs_board as e WHERE e.service_id= ?");
            }
            
            //qRecsBoardFcim1.setParameter("serviceId", serviceId);
            qRecsBoardFcim1.setParameter(1, serviceId);
            //Date ts = (Date) qRecsBoardFcim1.getSingleResult();
            Integer ts = (Integer) qRecsBoardFcim1.getSingleResult();
            
            if (qRecsBoardFcim2 == null) {
                //qRecsBoardFcim2 = jrecsboardc.getEntityManager().createQuery("SELECT e FROM FcimRecsBoard e WHERE e.serviceId = :serviceId AND e.timestampId.timestamp = :ts");
                qRecsBoardFcim2 = jrecsboardc.getEntityManager().createNativeQuery("SELECT * FROM fcim_recs_board as e WHERE e.service_id = ? AND e.timestamp_id = ?", FcimRecsBoard.class);
            }
            
            //qRecsBoardFcim2.setParameter("serviceId", serviceId);
            //qRecsBoardFcim2.setParameter("ts", ts);
            qRecsBoardFcim2.setParameter(1, serviceId);
            qRecsBoardFcim2.setParameter(2, ts);

            Collection<FcimRecsBoard> c = qRecsBoardFcim2.getResultList();
            Iterator<FcimRecsBoard> i = c.iterator();

            if (i.hasNext()) {
                FcimRecsBoard v = i.next();
                ret.addValue("board_it", new BigDecimal(v.getBoardId()));
                ret.addValue("temperature", new BigDecimal(v.getTemperature()));
                ret.addValue("power", new BigDecimal(v.getPower()));
            }
        } else if (nagiosTable.equalsIgnoreCase("fcim_vm_one")) {
            
            if (jvmonec == null)
                jvmonec = new FcimVmOneJpaController(emfFcim);

            if (qVmOneFcim1 == null)
                qVmOneFcim1 = jvmonec.getEntityManager().createQuery("SELECT MAX(e.timestampId.timestamp) FROM FcimVmOne e WHERE e.serviceId= :serviceId ");
            
            qVmOneFcim1.setParameter("serviceId", serviceId);
            Date ts = (Date) qVmOneFcim1.getSingleResult();
            
            if (qVmOneFcim2 == null)
                qVmOneFcim2 = jvmonec.getEntityManager().createQuery("SELECT e FROM FcimVmOne e WHERE e.serviceId = :serviceId AND e.timestampId.timestamp = :ts");
            
            qVmOneFcim2.setParameter("serviceId", serviceId);
            qVmOneFcim2.setParameter("ts", ts);

            Collection<FcimVmOne> c = qVmOneFcim2.getResultList();
            Iterator<FcimVmOne> i = c.iterator();

            if (i.hasNext()) {
                FcimVmOne v = i.next();
                ret.addValue("memory", new BigDecimal(v.getMemory()));
                ret.addValue("cpu_time", new BigDecimal(v.getCpuTime()));
                ret.addValue("cpu_usage_perc", new BigDecimal(v.getCpuUsagePerc()));
            }
        } else if (nagiosTable.equalsIgnoreCase("fcim_vms_one")) {
            
            if (jvmonec == null)
                jvmsonec = new FcimVmsOneJpaController(emfFcim);

            if (qVmsOneFcim1 == null)
                qVmsOneFcim1 = jvmsonec.getEntityManager().createQuery("SELECT MAX(e.timestampId.timestamp) FROM FcimVmsOne e WHERE e.serviceId= :serviceId ");
            
            qVmsOneFcim1.setParameter("serviceId", serviceId);
            Date ts = (Date) qVmsOneFcim1.getSingleResult();
            
            if (qVmsOneFcim2 == null)
                qVmsOneFcim2 = jvmsonec.getEntityManager().createQuery("SELECT e FROM FcimVmsOne e WHERE e.serviceId = :serviceId AND e.timestampId.timestamp = :ts");            
            
            qVmsOneFcim2.setParameter("serviceId", serviceId);
            qVmsOneFcim2.setParameter("ts", ts);

            Collection<FcimVmsOne> c = qVmsOneFcim2.getResultList();
            Iterator<FcimVmsOne> i = c.iterator();

            if (i.hasNext()) {
                FcimVmsOne v = i.next();
                ret.addValue("nr_running_vms", new BigDecimal(v.getNrRunningVms()));
            }
        } else if (nagiosTable.equalsIgnoreCase("fcim_cpu")) {
            
            if (jcpuc == null)
                jcpuc = new FcimCpuJpaController(emfFcim);

            if (qCpuFcim1 == null)
                qCpuFcim1 = jcpuc.getEntityManager().createQuery("SELECT MAX(e.timestampId.timestamp) FROM FcimCpu e WHERE e.serviceId= :serviceId ");
            
            qCpuFcim1.setParameter("serviceId", serviceId);
            Date ts = (Date) qCpuFcim1.getSingleResult();
            
            if (qCpuFcim2 == null)
                qCpuFcim2 = jcpuc.getEntityManager().createQuery("SELECT e FROM FcimCpu e WHERE e.serviceId = :serviceId AND e.timestampId.timestamp = :ts");            
            
            qCpuFcim2.setParameter("serviceId", serviceId);
            qCpuFcim2.setParameter("ts", ts);

            Collection<FcimCpu> c = qCpuFcim2.getResultList();
            Iterator<FcimCpu> i = c.iterator();

            if (i.hasNext()) {
                FcimCpu v = i.next();
                ret.addValue("allocation_perc", new BigDecimal(v.getAllocationPerc()));
                ret.addValue("usage_perc", new BigDecimal(v.getUsagePerc()));
            }
        } else if (nagiosTable.equalsIgnoreCase("fcim_cpu_load")) {
            
            if (jcpuloadc == null)
                jcpuloadc = new FcimCpuLoadJpaController(emfFcim);

            if (qCpuLoadFcim1 == null)
                qCpuLoadFcim1 = jcpuloadc.getEntityManager().createQuery("SELECT MAX(e.timestampId.timestamp) FROM FcimCpuLoad e WHERE e.serviceId= :serviceId ");
            
            qCpuLoadFcim1.setParameter("serviceId", serviceId);
            Date ts = (Date) qCpuLoadFcim1.getSingleResult();
            
            if (qCpuLoadFcim2 == null)
                qCpuLoadFcim2 = jcpuloadc.getEntityManager().createQuery("SELECT e FROM FcimCpuLoad e WHERE e.serviceId = :serviceId AND e.timestampId.timestamp = :ts");
            
            qCpuLoadFcim2.setParameter("serviceId", serviceId);
            qCpuLoadFcim2.setParameter("ts", ts);

            Collection<FcimCpuLoad> c = qCpuLoadFcim2.getResultList();
            Iterator<FcimCpuLoad> i = c.iterator();

            if (i.hasNext()) {
                FcimCpuLoad v = i.next();
                ret.addValue("average", new BigDecimal(v.getAverage()));
                ret.addValue("period", new BigDecimal(v.getPeriod()));
            }
        } else if (nagiosTable.equalsIgnoreCase("fcim_vm_consumption")) {
            
            if (jvmconsc == null)
                jvmconsc = new FcimVmConsumptionJpaController(emfFcim);

            if (qVmConsFcim1 == null)
                qVmConsFcim1 = jvmconsc.getEntityManager().createQuery("SELECT MAX(e.timestampId.timestamp) FROM FcimVmConsumption e WHERE e.serviceId= :serviceId ");
            
            qVmConsFcim1.setParameter("serviceId", serviceId);
            Date ts = (Date) qVmConsFcim1.getSingleResult();
            
            if (qVmConsFcim2 == null)
                qVmConsFcim2 = jvmconsc.getEntityManager().createQuery("SELECT e FROM FcimVmConsumption e WHERE e.serviceId = :serviceId AND t.timestamp = :ts");
            
            qVmConsFcim2.setParameter("serviceId", serviceId);
            qVmConsFcim2.setParameter("ts", ts);

            Collection<FcimVmConsumption> c = qVmConsFcim2.getResultList();
            Iterator<FcimVmConsumption> i = c.iterator();

            if (i.hasNext()) {
                FcimVmConsumption v = i.next();
                ret.addValue("power", new BigDecimal(v.getPower()));
            }
        } else if (nagiosTable.equalsIgnoreCase("fcim_env_consumption")) {
            
            if (jenvconsc == null)
                jenvconsc = new FcimEnvConsumptionJpaController(emfFcim);

            if (qEnvConsFcim1 == null)
                qEnvConsFcim1 = jenvconsc.getEntityManager().createQuery("SELECT MAX(e.timestampId.timestamp) FROM FcimEnvConsumption e WHERE e.serviceId= :serviceId ");            
            
            qEnvConsFcim1.setParameter("serviceId", serviceId);
            Date ts = (Date) qEnvConsFcim1.getSingleResult();
            
            if (qEnvConsFcim2 == null)
                qEnvConsFcim2 = jenvconsc.getEntityManager().createQuery("SELECT e FROM FcimEnvConsumption e WHERE e.serviceId = :serviceId AND e.timestampId.timestamp = :ts");
            
            qEnvConsFcim2.setParameter("serviceId", serviceId);
            qEnvConsFcim2.setParameter("ts", ts);

            Collection<FcimEnvConsumption> c = qEnvConsFcim2.getResultList();
            Iterator<FcimEnvConsumption> i = c.iterator();

            if (i.hasNext()) {
                FcimEnvConsumption v = i.next();
                ret.addValue("current", new BigDecimal(v.getCurrent()));
                ret.addValue("energy", new BigDecimal(v.getEnergy()));
                ret.addValue("kva", new BigDecimal(v.getKva()));
                ret.addValue("kwatts", new BigDecimal(v.getKwatts()));
                ret.addValue("voltage", new BigDecimal(v.getVoltage()));
            }
        } else if (nagiosTable.equalsIgnoreCase("fcim_env_air")) {
            
            if (jenvairc == null)
                jenvairc = new FcimEnvAirJpaController(emfFcim);

            if (qEnvAirFcim1 == null)
                qEnvAirFcim1 = jenvairc.getEntityManager().createQuery("SELECT MAX(e.timestampId.timestamp) FROM FcimEnvAir e WHERE e.serviceId= :serviceId ");
            
            qEnvAirFcim1.setParameter("serviceId", serviceId);
            Date ts = (Date) qEnvAirFcim1.getSingleResult();
            
            if (qEnvAirFcim2 == null)
                qEnvAirFcim2 = jenvairc.getEntityManager().createQuery("SELECT e FROM FcimEnvAir e WHERE e.serviceId = :serviceId AND e.timestampId.timestamp = :ts");            
            
            qEnvAirFcim2.setParameter("serviceId", serviceId);
            qEnvAirFcim2.setParameter("ts", ts);

            Collection<FcimEnvAir> c = qEnvAirFcim2.getResultList();
            Iterator<FcimEnvAir> i = c.iterator();

            if (i.hasNext()) {
                FcimEnvAir v = i.next();
                ret.addValue("intake_temperature", new BigDecimal(v.getIntakeTemperature()));
                ret.addValue("outlet_temperature", new BigDecimal(v.getOutletTemperature()));
            }
        } else if (nagiosTable.equalsIgnoreCase("fcim_network")) {
            
            if (jnetc == null)
                jnetc = new FcimNetworkJpaController(emfFcim);

            if (qNetworkFcim1 == null)
                qNetworkFcim1 = jnetc.getEntityManager().createQuery("SELECT MAX(e.timestampId.timestamp) FROM FcimNetwork e WHERE e.serviceId= :serviceId ");
            
            qNetworkFcim1.setParameter("serviceId", serviceId);
            Date ts = (Date) qNetworkFcim1.getSingleResult();
            
            if (qNetworkFcim2 == null)
                qNetworkFcim2 = jnetc.getEntityManager().createQuery("SELECT e FROM FcimNetwork e WHERE e.serviceId = :serviceId AND e.timestampId.timestamp = :ts");
            
            qNetworkFcim2.setParameter("serviceId", serviceId);
            qNetworkFcim2.setParameter("ts", ts);

            Collection<FcimNetwork> c = qNetworkFcim2.getResultList();
            Iterator<FcimNetwork> i = c.iterator();

            if (i.hasNext()) {
                FcimNetwork v = i.next();
                ret.addValue("power", new BigDecimal(v.getPower()));
            }
        } else if (nagiosTable.equalsIgnoreCase("fcim_server_ping")) {
            
            if (jservpingc == null)
                jservpingc = new FcimServerPingJpaController(emfFcim);

            if (qServerPingFcim1 == null)
                qServerPingFcim1 = jservpingc.getEntityManager().createQuery("SELECT MAX(e.timestampId.timestamp) FROM FcimServerPing e WHERE e.serviceId= :serviceId ");
            
            qServerPingFcim1.setParameter("serviceId", serviceId);
            Date ts = (Date) qServerPingFcim1.getSingleResult();
            
            if (qServerPingFcim2 == null)
                qServerPingFcim2 = jservpingc.getEntityManager().createQuery("SELECT e FROM FcimServerPing e WHERE e.serviceId = :serviceId AND e.timestampId.timestamp = :ts");
            
            qServerPingFcim2.setParameter("serviceId", serviceId);
            qServerPingFcim2.setParameter("ts", ts);
            Collection<FcimServerPing> c = qServerPingFcim2.getResultList();
            Iterator<FcimServerPing> i = c.iterator();

            if (i.hasNext()) {
                FcimServerPing v = i.next();
                ret.addValue("packet_loss", new BigDecimal(v.getPacketLoss()));
                ret.addValue("rta", new BigDecimal(v.getRta()));
            }
        } else if (nagiosTable.equalsIgnoreCase("fcim_env_humidity")) {
            
            if (jenvhumc == null)
                jenvhumc = new FcimEnvHumidityJpaController(emfFcim);

            if (qEnvHumidityFcim1 == null)
                qEnvHumidityFcim1 = jenvhumc.getEntityManager().createQuery("SELECT MAX(e.timestampId.timestamp) FROM FcimEnvHumidity e WHERE e.serviceId= :serviceId ");
            
            qEnvHumidityFcim1.setParameter("serviceId", serviceId);
            Date ts = (Date) qEnvHumidityFcim1.getSingleResult();
            
            if (qEnvHumidityFcim2 == null)
                qEnvHumidityFcim2 = jenvhumc.getEntityManager().createQuery("SELECT e FROM FcimEnvHumidity e WHERE e.serviceId = :serviceId AND e.timestampId.timestamp = :ts");
            
            qEnvHumidityFcim2.setParameter("serviceId", serviceId);
            qEnvHumidityFcim2.setParameter("ts", ts);

            Collection<FcimEnvHumidity> c = qEnvHumidityFcim2.getResultList();
            Iterator<FcimEnvHumidity> i = c.iterator();

            if (i.hasNext()) {
                FcimEnvHumidity v = i.next();
                ret.addValue("percentage", new BigDecimal(v.getPercentage()));
            }
        } else if (nagiosTable.equalsIgnoreCase("fcim_kernel")) {
            
            if (jkernc == null)
                jkernc = new FcimKernelJpaController(emfFcim);

            if (qKernelFcim1 == null)
                qKernelFcim1 = jkernc.getEntityManager().createQuery("SELECT MAX(e.timestampId.timestamp) FROM FcimKernel e WHERE e.serviceId= :serviceId ");
            
            qKernelFcim1.setParameter("serviceId", serviceId);
            Date ts = (Date) qKernelFcim1.getSingleResult();
            
            if (qKernelFcim2 == null)
                qKernelFcim2 = jkernc.getEntityManager().createQuery("SELECT e FROM FcimKernel e WHERE e.serviceId = :serviceId AND e.timestampId.timestamp = :ts");
            qKernelFcim2.setParameter("serviceId", serviceId);
            qKernelFcim2.setParameter("ts", ts);

            Collection<FcimKernel> c = qKernelFcim2.getResultList();
            Iterator<FcimKernel> i = c.iterator();

            if (i.hasNext()) {
                FcimKernel v = i.next();
                ret.addValue("performance", new BigDecimal(v.getPerformance()));
            }
        } else if (nagiosTable.equalsIgnoreCase("fcim_cpu_fan")) {
            
            if (jcpufanc == null)
                jcpufanc = new FcimCpuFanJpaController(emfFcim);

            if (qCpuFanFcim1 == null)
                qCpuFanFcim1 = jcpufanc.getEntityManager().createQuery("SELECT MAX(e.timestampId.timestamp) FROM FcimCpuFan e WHERE e.serviceId= :serviceId ");
            
            qCpuFanFcim1.setParameter("serviceId", serviceId);
            Date ts = (Date) qCpuFanFcim1.getSingleResult();
            
            if (qCpuFanFcim2 == null)
                qCpuFanFcim2 = jcpufanc.getEntityManager().createQuery("SELECT e FROM FcimCpuFan e WHERE e.serviceId = :serviceId AND e.timestampId.timestamp = :ts");
            qCpuFanFcim2.setParameter("serviceId", serviceId);
            qCpuFanFcim2.setParameter("ts", ts);

            Collection<FcimCpuFan> c = qCpuFanFcim2.getResultList();
            Iterator<FcimCpuFan> i = c.iterator();

            if (i.hasNext()) {
                FcimCpuFan v = i.next();
                ret.addValue("speed", new BigDecimal(v.getSpeed()));
            }
        } else if (nagiosTable.equalsIgnoreCase("fcim_env_temperature")) {
            
            if (jenvtempc == null)
                jenvtempc = new FcimEnvTemperatureJpaController(emfFcim);

            if (qEnvTempFcim1 == null)
                qEnvTempFcim1 = jenvtempc.getEntityManager().createQuery("SELECT MAX(e.timestampId.timestamp) FROM FcimEnvTemperature e WHERE e.serviceId= :serviceId ");
            qEnvTempFcim1.setParameter("serviceId", serviceId);
            Date ts = (Date) qEnvTempFcim1.getSingleResult();
            
            if (qEnvTempFcim2 == null)
                qEnvTempFcim2 = jenvtempc.getEntityManager().createQuery("SELECT e FROM FcimEnvTemperature e WHERE e.serviceId = :serviceId AND e.timestampId.timestamp = :ts");
            qEnvTempFcim2.setParameter("serviceId", serviceId);
            qEnvTempFcim2.setParameter("ts", ts);

            Collection<FcimEnvTemperature> c = qEnvTempFcim2.getResultList();
            Iterator<FcimEnvTemperature> i = c.iterator();

            if (i.hasNext()) {
                FcimEnvTemperature v = i.next();
                ret.addValue("temperature", new BigDecimal(v.getTemperature()));
            }
        } else if (nagiosTable.equalsIgnoreCase("fcim_temperature")) {
            
            if (jtempc == null)
                jtempc = new FcimTemperatureJpaController(emfFcim);

            if (qTempFcim1 == null)
                qTempFcim1 = jtempc.getEntityManager().createQuery("SELECT MAX(e.timestampId.timestamp) FROM FcimTemperature e WHERE e.serviceId= :serviceId ");
            
            qTempFcim1.setParameter("serviceId", serviceId);
            Date ts = (Date) qTempFcim1.getSingleResult();
            
            if (qTempFcim2 == null)
                qTempFcim2 = jtempc.getEntityManager().createQuery("SELECT e FROM FcimTemperature e WHERE e.serviceId = :serviceId AND e.timestampId.timestamp = :ts");
            
            qTempFcim2.setParameter("serviceId", serviceId);
            qTempFcim2.setParameter("ts", ts);

            Collection<FcimTemperature> c = qTempFcim2.getResultList();
            Iterator<FcimTemperature> i = c.iterator();

            if (i.hasNext()) {
                FcimTemperature v = i.next();
                ret.addValue("temperature", new BigDecimal(v.getTemperature()));
            }
        } else if (nagiosTable.equalsIgnoreCase("fcim_processes")) {
            
            if (jprocsc == null)
                jprocsc = new FcimProcessesJpaController(emfFcim);

            if (qProcessesFcim1 == null)
                qProcessesFcim1 = jprocsc.getEntityManager().createQuery("SELECT MAX(e.timestampId.timestamp) FROM FcimProcesses e WHERE e.serviceId= :serviceId ");
            
            qProcessesFcim1.setParameter("serviceId", serviceId);
            Date ts = (Date) qProcessesFcim1.getSingleResult();
            
            if (qProcessesFcim2 == null)
                qProcessesFcim2 = jprocsc.getEntityManager().createQuery("SELECT e FROM FcimProcesses e WHERE e.serviceId = :serviceId AND e.timestampId.timestamp = :ts");
            
            qProcessesFcim2.setParameter("serviceId", serviceId);
            qProcessesFcim2.setParameter("ts", ts);

            Collection<FcimProcesses> c = qProcessesFcim2.getResultList();
            Iterator<FcimProcesses> i = c.iterator();

            if (i.hasNext()) {
                FcimProcesses v = i.next();
                ret.addValue("nr_processes", new BigDecimal(v.getNrProcesses()));
            }
        } else if (nagiosTable.equalsIgnoreCase("fcim_cpu_one")) {
            
            if (jcpuonec == null)
                jcpuonec = new FcimCpuOneJpaController(emfFcim);

            if (qCpuOneFcim1 == null)            
                qCpuOneFcim1 = jcpuonec.getEntityManager().createQuery("SELECT MAX(e.timestampId.timestamp) FROM FcimCpuOne e WHERE e.serviceId= :serviceId ");
            
            qCpuOneFcim1.setParameter("serviceId", serviceId);
            Date ts = (Date) qCpuOneFcim1.getSingleResult();
            
            if (qCpuOneFcim2 == null)
                qCpuOneFcim2 = jcpuonec.getEntityManager().createQuery("SELECT e FROM FcimCpuOne e WHERE e.serviceId = :serviceId AND e.timestampId.timestamp = :ts");
            
            qCpuOneFcim2.setParameter("serviceId", serviceId);
            qCpuOneFcim2.setParameter("ts", ts);

            Collection<FcimCpuOne> c = qCpuOneFcim2.getResultList();
            Iterator<FcimCpuOne> i = c.iterator();

            if (i.hasNext()) {
                FcimCpuOne v = i.next();
                ret.addValue("allocated", new BigDecimal(v.getAllocated()));
                ret.addValue("total", new BigDecimal(v.getTotal()));
                ret.addValue("free", new BigDecimal(v.getFree()));
                ret.addValue("used", new BigDecimal(v.getUsed()));
            }
        } else if (nagiosTable.equalsIgnoreCase("fcim_hdd_one")) {
            
            if (jhddonec == null)
                jhddonec = new FcimHddOneJpaController(emfFcim);

            if (qHddOneFcim1 == null)
                qHddOneFcim1 = jhddonec.getEntityManager().createQuery("SELECT MAX(e.timestampId.timestamp) FROM FcimHddOne e WHERE e.serviceId= :serviceId ");
            
            qHddOneFcim1.setParameter("serviceId", serviceId);
            Date ts = (Date) qHddOneFcim1.getSingleResult();
            
            if (qHddOneFcim2 == null)
                qHddOneFcim2 = jhddonec.getEntityManager().createQuery("SELECT e FROM FcimHddOne e WHERE e.serviceId = :serviceId AND e.timestampId.timestamp = :ts");
            
            qHddOneFcim2.setParameter("serviceId", serviceId);
            qHddOneFcim2.setParameter("ts", ts);

            Collection<FcimHddOne> c = qHddOneFcim2.getResultList();
            Iterator<FcimHddOne> i = c.iterator();

            if (i.hasNext()) {
                FcimHddOne v = i.next();
                ret.addValue("allocated", new BigDecimal(v.getAllocated()));
                ret.addValue("total", new BigDecimal(v.getTotal()));
                ret.addValue("free", new BigDecimal(v.getFree()));
                ret.addValue("used", new BigDecimal(v.getUsed()));
                ret.addValue("usage_perc", new BigDecimal(v.getUsagePerc()));
            }
        } else if (nagiosTable.equalsIgnoreCase("fcim_ram_one")) {
            
            if (jramonec == null)              
                jramonec = new FcimRamOneJpaController(emfFcim);

            if (qRamOneFcim1 == null)
                qRamOneFcim1 = jramonec.getEntityManager().createQuery("SELECT MAX(e.timestampId.timestamp) FROM FcimRamOne e WHERE e.serviceId= :serviceId ");
            
            qRamOneFcim1.setParameter("serviceId", serviceId);
            Date ts = (Date) qRamOneFcim1.getSingleResult();
            
            if (qRamOneFcim2 == null)
                qRamOneFcim2 = jramonec.getEntityManager().createQuery("SELECT e FROM FcimRamOne e WHERE e.serviceId = :serviceId AND e.timestampId.timestamp = :ts");
            qRamOneFcim2.setParameter("serviceId", serviceId);
            qRamOneFcim2.setParameter("ts", ts);

            Collection<FcimRamOne> c = qRamOneFcim2.getResultList();
            Iterator<FcimRamOne> i = c.iterator();

            if (i.hasNext()) {
                FcimRamOne v = i.next();
                ret.addValue("allocated", new BigDecimal(v.getAllocated()));
                ret.addValue("allocation_perc", new BigDecimal(v.getAllocationPerc()));
            }
        } else if (nagiosTable.equalsIgnoreCase("fcim_activity")) {
            
            if (jactivityc == null)
                jactivityc = new FcimActivityJpaController(emfFcim);

            if (qActivityFcim1 == null)
                qActivityFcim1 = jactivityc.getEntityManager().createQuery("SELECT MAX(e.timestampId.timestamp) FROM FcimActivity e WHERE e.serviceId= :serviceId ");
            qActivityFcim1.setParameter("serviceId", serviceId);
            Date ts = (Date) qActivityFcim1.getSingleResult();
            
            if (qActivityFcim2 == null)
                qActivityFcim2 = jactivityc.getEntityManager().createQuery("SELECT e FROM FcimActivity e WHERE e.serviceId = :serviceId AND e.timestampId.timestamp = :ts");
            qActivityFcim2.setParameter("serviceId", serviceId);
            qActivityFcim2.setParameter("ts", ts);

            Collection<FcimActivity> c = qActivityFcim2.getResultList();
            Iterator<FcimActivity> i = c.iterator();

            if (i.hasNext()) {
                FcimActivity v = i.next();
                ret.addValue("reading", new BigDecimal(v.getReading()));
                ret.addValue("writing", new BigDecimal(v.getWriting()));
            }
        } else if (nagiosTable.equalsIgnoreCase("fcim_storage")) {
            
            if (jstoragec == null)
                jstoragec = new FcimStorageJpaController(emfFcim);

            if (qStorageFcim1 == null)
                qStorageFcim1 = jstoragec.getEntityManager().createQuery("SELECT MAX(e.timestampId.timestamp) FROM FcimStorage e WHERE e.serviceId= :serviceId ");
            
            qStorageFcim1.setParameter("serviceId", serviceId);
            Date ts = (Date) qStorageFcim1.getSingleResult();
            
            if (qStorageFcim2 == null)
                qStorageFcim2 = jstoragec.getEntityManager().createQuery("SELECT e FROM FcimStorage e WHERE e.serviceId = :serviceId AND e.timestampId.timestamp = :ts");
            qStorageFcim2.setParameter("serviceId", serviceId);
            qStorageFcim2.setParameter("ts", ts);

            Collection<FcimStorage> c = qStorageFcim2.getResultList();
            Iterator<FcimStorage> i = c.iterator();

            if (i.hasNext()) {
                FcimStorage v = i.next();
                ret.addValue("space_allocated", new BigDecimal(v.getSpaceAllocated()));
                ret.addValue("space_free", new BigDecimal(v.getSpaceFree()));
                ret.addValue("space_total", new BigDecimal(v.getSpaceTotal()));
                ret.addValue("space_used_perc", new BigDecimal(v.getSpaceUsedPerc()));
                ret.addValue("average_measured_power", new BigDecimal(v.getAverageMeasuredPower()));
                ret.addValue("averaging_interval", new BigDecimal(v.getAveragingInterval()));
                ret.addValue("iops_read", new BigDecimal(v.getIopsRead()));
                ret.addValue("iops_write", new BigDecimal(v.getIopsWrite()));
                ret.addValue("iops_total", new BigDecimal(v.getIopsTotal()));
                ret.addValue("sequential_portion_perc", new BigDecimal(v.getSequentialPortionPerc()));
                ret.addValue("responsetime_measured", new BigDecimal(v.getResponsetimeMeasured()));
                ret.addValue("queue_length", new BigDecimal(v.getQueueLength()));
                ret.addValue("throughput_read", new BigDecimal(v.getThroughputRead()));
                ret.addValue("throughput_write", new BigDecimal(v.getThroughputWrite()));
                ret.addValue("throughput_total", new BigDecimal(v.getThroughputTotal()));
                ret.addValue("storage_mode", new BigDecimal(v.getStorageMode()));
            }
        } else if (nagiosTable.equalsIgnoreCase("fcim_performance_counter")) {
            
            if (jperformancec == null)
                jperformancec = new FcimPerformanceCounterJpaController(emfFcim);

            if (qPerformanceFcim1 == null) {
                //qPerformanceFcim1 = jperformancec.getEntityManager().createQuery("SELECT MAX(e.timestampId.timestamp) FROM FcimPerformanceCounter e WHERE e.serviceId= :serviceId ");
                qPerformanceFcim1 = jperformancec.getEntityManager().createNativeQuery("SELECT MAX(e.timestamp_id) FROM fcim_performance_counter as e WHERE e.service_id = ?");
            }
            
            //qPerformanceFcim1.setParameter("serviceId", serviceId);
            qPerformanceFcim1.setParameter(1, serviceId);
            //Date ts = (Date) qPerformanceFcim1.getSingleResult();
            Integer ts = (Integer) qPerformanceFcim1.getSingleResult();
            
            if (qPerformanceFcim2 == null) {
                //qPerformanceFcim2 = jperformancec.getEntityManager().createQuery("SELECT e FROM FcimPerformanceCounter e WHERE e.serviceId = :serviceId AND e.timestampId.timestamp = :ts");
                qPerformanceFcim2 = jperformancec.getEntityManager().createNativeQuery("SELECT sum(scir_packed) AS A, sum(scir_scalar) AS B, min(start_of_measure) AS C, max(end_of_measure) AS D FROM fcim_performance_counter as e WHERE e.service_id = ? AND e.timestamp_id = ? GROUP BY e.service_id, e.core_id");
            }
            //qPerformanceFcim2.setParameter("serviceId", serviceId);
            //qPerformanceFcim2.setParameter("ts", ts);            
            qPerformanceFcim2.setParameter(1, serviceId);
            qPerformanceFcim2.setParameter(2, ts);            

            List<Object> c = qPerformanceFcim2.getResultList();

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

            for (Object line : c) {
                
                Object[] attributes = (Object[]) line;
                
                for (int i=0; i<attributes.length; i++) {
                    
                    ret.addValue("start_of_measure", new BigDecimal(((Timestamp)attributes[2]).getTime()));
                    ret.addValue("end_of_measure", new BigDecimal(((Timestamp)attributes[3]).getTime()));
                    ret.addValue("scir_packed", new BigDecimal((Double)attributes[0]));
                    ret.addValue("scir_scalar", new BigDecimal((Double)attributes[1]));
                    
                }

                                
                //ret.addValue("start_of_measure", new BigDecimal(v.getStartOfMeasure().getTime()));
                //ret.addValue("end_of_measure", new BigDecimal(v.getEndOfMeasure().getTime()));
                //ret.addValue("scir_packed", new BigDecimal(v.getScirPacked()));
                //ret.addValue("scir_scalar", new BigDecimal(v.getScirScalar()));
                //System.out.println("FLOP " + ((v.getScirPacked() * 2) + v.getScirScalar()));
                //System.out.println("Time " + (v.getEndOfMeasure().getTime()-v.getStartOfMeasure().getTime()));
            }
        }

        return ret;
    }
}

class FcimCache {

    String nagiosTable;
    String serviceId;
    HashMap hp;

    FcimCache(String nagiosTable, String serviceId) {
        this.nagiosTable = nagiosTable;
        this.serviceId = serviceId;
        hp = new HashMap();
    }

    BigDecimal getParamValue(String nagiosTable, String nagiosField, String serviceId) {
        BigDecimal res = null;
        if (this.nagiosTable.equalsIgnoreCase(nagiosTable) && this.serviceId.equalsIgnoreCase(serviceId) && hp.containsKey(nagiosField)) {
            res = (BigDecimal) hp.get(nagiosField);
        }
        return res;
    }

    void addValue(String nagiosField, BigDecimal value) {
        hp.put(nagiosField, value);
    }

    boolean isPresent(String nagiosTable, String nagiosField, String serviceId) {
        if (this.nagiosTable.equalsIgnoreCase(nagiosTable) && this.serviceId.equalsIgnoreCase(serviceId) && hp.containsKey(nagiosField)) {
            return true;
        } else {
            return false;
        }
    }
}